package com.andkrup.customization {
	import com.andkrup.events.PreferencesEvent;	
	
	import flash.display.DisplayObjectContainer;
	import flash.display.LoaderInfo;
	import flash.events.Event;
	import flash.events.SecurityErrorEvent;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.utils.Dictionary;

	/**
	 * @author Andkrup
	 */
	public class PreferencesManager extends EventDispatcher implements IEventDispatcher {
		public static const FV_CFGPATH:String = "path";
		public static const FV_BUILDERPATH:String = "main";
		public static const FV_DEVMODE:String = "dev";
		
		private static var _inst:PreferencesManager;
		private static var _base:DisplayObjectContainer;
		private static var _cfgPath:String = "assets/cfg.xml";
		private static var _devMode:Boolean = false;
		
		public var cfgXml:XML;
		public var builderPath:String = "assets/builder.swf";
		
		private var xmlLoader:URLLoader;
		private var flashvars:Dictionary;
		private var fvLoaded:Boolean;
		
		public static function get devMode():Boolean{
			return _devMode;
		}
		
		public static function get instance():PreferencesManager{
			if(!_inst) _inst = new PreferencesManager(new PreferencesManagerConstructor());
			return _inst;
		}
		
		public function PreferencesManager(ctr:PreferencesManagerConstructor) {
			super();
			ctr = undefined;
			flashvars = new Dictionary();
		}
		
		public function init(base:DisplayObjectContainer, path:String = null, mainSwfPath:String = null, devEnabled:Boolean = false):void{
			_base = base;
			
			var obj:Object = LoaderInfo(_base.root.loaderInfo).parameters;
			// look for specific vars
			// check for alternate config-path in flashvars collection
			if(obj[FV_CFGPATH]) if(!path) path = String(obj[FV_CFGPATH]);
			// check for alternate builder-path in flashvars collection
			if(obj[FV_BUILDERPATH]) if(!mainSwfPath) mainSwfPath = String(obj[FV_BUILDERPATH]);
			// check for dev-mode flag - applications must be compiled with devEnabled parameter set to true
			if(obj[FV_DEVMODE]) if(true==devEnabled) _devMode = Boolean(obj[FV_DEVMODE]);
			// look for other vars
			var k:String;
			for(k in obj) {
				flashvars[k] = String(obj[k]);
			}
			
			if(mainSwfPath) builderPath = mainSwfPath;
			 
			fvLoaded = true;
			
			if(hasEventListener(PreferencesEvent.FLASHVARS)) dispatchEvent(new PreferencesEvent(PreferencesEvent.FLASHVARS));
			// if alternate paths was found, load config from path, else load from default _cfgPath
			loadConfig(path ? path : _cfgPath);
		}
		
		public function getFlashVar(key:String):String{
			return flashvars[key];
		}
		
		public function loadConfig(path:String, forceLoad:Boolean = false):void{
			if(xmlLoader){
				if(forceLoad){
					xmlLoader.removeEventListener(Event.COMPLETE, onLoaderComplete);
					xmlLoader.removeEventListener(IOErrorEvent.IO_ERROR, onLoaderIOError);
					xmlLoader.removeEventListener(ProgressEvent.PROGRESS, onLoaderProgress);
					xmlLoader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onLoaderSecurityError);
				}
				else{
					trace("preferencesmanager:> config is already loading from path: "+_cfgPath);
					return;
				}
			}
			_cfgPath = path;
			xmlLoader = new URLLoader();
			xmlLoader.addEventListener(Event.COMPLETE, onLoaderComplete);
			xmlLoader.addEventListener(IOErrorEvent.IO_ERROR, onLoaderIOError);
			xmlLoader.addEventListener(ProgressEvent.PROGRESS, onLoaderProgress);
			xmlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onLoaderSecurityError);
			
			var req:URLRequest = new URLRequest(path);
			xmlLoader.load(req);
		}
		
		private function onLoaderComplete(e:Event):void{
			cfgXml = new XML(xmlLoader.data);
			
			xmlLoader.removeEventListener(Event.COMPLETE, onLoaderComplete);
			xmlLoader.removeEventListener(IOErrorEvent.IO_ERROR, onLoaderIOError);
			xmlLoader.removeEventListener(ProgressEvent.PROGRESS, onLoaderProgress);
			xmlLoader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onLoaderSecurityError);
			xmlLoader = undefined;
			
			if(hasEventListener(PreferencesEvent.CONFIG)) dispatchEvent(new PreferencesEvent(PreferencesEvent.CONFIG));
			if(fvLoaded && cfgXml) dispatchEvent(new Event(Event.COMPLETE));
		}
		private function onLoaderIOError(ioee:IOErrorEvent):void{
			dispatchEvent(ioee.clone());
		}
		private function onLoaderProgress(pe:ProgressEvent):void{
			dispatchEvent(pe.clone());
		}
		private function onLoaderSecurityError(see:SecurityErrorEvent):void{
			dispatchEvent(see.clone());
		}
	}
}
class PreferencesManagerConstructor{}